package 中等.模拟;

/**
 * 位集 Bitset 是一种能以紧凑形式存储位的数据结构。
 * 请你实现 Bitset 类。
 * Bitset(int size) 用 size 个位初始化 Bitset ，所有位都是 0 。
 * void fix(int idx) 将下标为 idx 的位上的值更新为 1 。如果值已经是 1 ，则不会发生任何改变。
 * void unfix(int idx) 将下标为 idx 的位上的值更新为 0 。如果值已经是 0 ，则不会发生任何改变。
 * void flip() 翻转 Bitset 中每一位上的值。换句话说，所有值为 0 的位将会变成 1 ，反之亦然。
 * boolean all() 检查 Bitset 中 每一位 的值是否都是 1 。如果满足此条件，返回 true ；否则，返回 false 。
 * boolean one() 检查 Bitset 中 是否 至少一位 的值是 1 。如果满足此条件，返回 true ；否则，返回 false 。
 * int count() 返回 Bitset 中值为 1 的位的 总数 。
 * String toString() 返回 Bitset 的当前组成情况。注意，在结果字符串中，第 i 个下标处的字符应该与 Bitset 中的第 i 位一致。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/design-bitset
 */
public class 设计位集_2166 {

    public static void main(String[] args) {

        System.out.println(true ^ true);
        System.out.println(false ^ true);

        System.out.println(1 ^ 1);
        System.out.println(0 ^ 1);

    }

    /**
     * 1，使用数组模拟
     * 2，使用一个变量维护 1 的总个数
     * 3，翻转每一位的值，不必真的去翻转，使用一个变量记录，1 是 1,
     * 0 是 0 ，还是 1是 0 ，0 是 1
     */
    class Bitset {

        private int[] bits;

        private int sumOne;

        private boolean isNormal = true;

        public Bitset(int size) {
            bits = new int[size];
        }

        public void fix(int idx) {
            if (isNormal) {
                if (bits[idx] == 0) {
                    sumOne++;
                }
                bits[idx] = 1;
            } else {
                if (bits[idx] == 1) {
                    sumOne++;
                }
                bits[idx] = 0;
            }
        }

        public void unfix(int idx) {
            if (isNormal) {
                if (bits[idx] == 1) {
                    sumOne--;
                }
                bits[idx] = 0;
            } else {
                if (bits[idx] == 0) {
                    sumOne--;
                }
                bits[idx] = 1;
            }
        }

        public void flip() {
            isNormal ^= true;
            sumOne = bits.length - sumOne;
        }

        public boolean all() {
            return sumOne == bits.length;
        }

        public boolean one() {
            return sumOne > 0;
        }

        public int count() {
            return sumOne;
        }

        public String toString() {
            StringBuilder stringBuilder = new StringBuilder();
            for (int bit : bits) {
                if (isNormal) {
                    stringBuilder.append(bit);
                } else {
                    stringBuilder.append(bit ^ 1);
                }
            }
            return stringBuilder.toString();
        }
    }

}
